# -*- coding: UTF-8 -*-

import datetime
import sys
from sqlalchemy import and_,  func, or_
from typing import Dict, List, Any, Generator

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, distinct
from sqlalchemy.orm import Session, relationship
from app.manage_notice.models.manage_notice_team import ManageNoticeTeam
from app.monitor_metrics.models.prom_alarm_metrics import PromAlarmMetrics
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger


__all__ = ['PromAlarmRule']


class PromAlarmRule(Base, SessionMixin):
    '''
    prometheus告警规则
    '''
    __tablename__ = "prom_alarm_rule"
    name = Column(String(256), nullable=False, index=True, comment='规则名称')
    # host主机 or k8s容器
    classes = Column(String(128), nullable=False, index=False, comment='规则分类')
    # record(记录规则) or alarm(告警规则)
    type = Column(String(16), nullable=False, comment='规则类型')
    # true/false
    state = Column(Boolean, default=text('true'), nullable=False, comment='激活状态')
    # true/false
    custom = Column(Boolean, default=text('true'), nullable=False, comment='是否是自定义规则')
    target = Column(String(128), nullable=False, index=False, comment='监控目标')
    alarm_metrics_uuid = Column(Integer, nullable=False, comment='告警指标的uuid')
    alarm_metrics_parm = Column(JSON, nullable=True, default={}, comment='告警指标的参数')
    # > < == !=
    operator = Column(String(16), nullable=True, default="", comment='运算符')
    value = Column(String(64), nullable=True, default="", comment='告警阀值')
    duration = Column(Integer, nullable=True, default=5, comment='持续分钟')
    notice_teams_uuid =  Column(JSON, nullable=True, default=[], comment='告警通知组')
    notice_count = Column(Integer, nullable=True, comment='告警通知次数')
    # critical:严重(电话部门负责人), major:重要警告(电话告警处理人), warning:一般告警(短信告警处理人),
    # info:提示告警(企业微信告警处理人), nothing:(不告警)
    level = Column(String(16), nullable=True, default="info", comment='告警级别')
    maintain_begin = Column(DateTime, nullable=True, comment='屏蔽开始时间')
    maintain_end = Column(DateTime, nullable=True, comment='屏蔽结束时间')
    maintain_repeat = Column(Boolean, nullable=True, comment='屏蔽时间是每天')
    callback = Column(String(256), nullable=True, default="",comment='回调接口')
    labels = Column(JSON, nullable=True, default={}, comment='标签')
    annotations = Column(JSON, nullable=True, default={}, comment='附加信息')
    comment = Column(String(256), nullable=True, default="",comment='规则说明')

    alarm_group_uuid = Column(Integer, ForeignKey('prom_alarm_group.uuid'), comment='告警组')

    __table_args__ = (
        Index('idx_prom_alarm_rules_name', 'name', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic'
        }
    )

    def __repr__(self):
        return f"<prom_alarm_rules='{self.name}>"


    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        result["alarm_group"] = self.prom_alarm_group.name
        alarm_metrics_object = PromAlarmMetrics.get_object_by_uuid(db, result["alarm_metrics_uuid"])
        if alarm_metrics_object:
            result["alarm_metrics_name"] = alarm_metrics_object.name

        # 方便前端直接展示名称
        result["notice_teams_name"] = []
        if result["notice_teams_uuid"]:
            for notice_team_uuid in result["notice_teams_uuid"]:
                notice_team_info = ManageNoticeTeam.get_object_info_by_uuid(db, notice_team_uuid)
                result["notice_teams_name"].append(notice_team_info["name"])
        return result


    @classmethod
    def get_object_info_by_notice_team(cls, db: Session, notice_team_uuid: str):
        object_info = db.query(cls).filter(
            func.json_contains(cls.notice_teams_uuid, str(notice_team_uuid)) == 1
        ).to_dict()

        return object_info